﻿using ArtMath.Attribute;
using ArtMath.Component.Point;
using ArtMath.Core.Data;
using ArtMath.Core.Helper;
using ArtMath.Flag;
using ArtMath.PointCollection;
using ArtMath.Resource;
using System;
using System.Collections.Generic;

namespace ArtMath.Component.Line
{
    /// <summary>
    /// 两点射线
    /// </summary>
    [Serializable]
    public class TwoPointsRay : RayBase
    {
        public TwoPointsRay(SketchPad pad, string name, bool addToList = true) : base(pad, name, ToolTypeName.ldsx, addToList)
        {
            InPoints = new PointBase[2];
        }
        [MultilingualCategory("Structure"), MultilingualDisplayName(null, "Direction", "Point")]
        public PointBase DirectionPoint
        {
            get { return InPoints[1]; }
            set { SetPoint(1, value); }
        }
        public override void ComponentChanged(ShapeBase component)
        {
            if (component == SourcePoint || component == DirectionPoint)
            {
                Slope = NewSlope;
                PSlope = NewPSlope;
            }
            base.ComponentChanged(component);
        }
        public override void ComponentBuilding(Base component)
        {
            if (SourcePoint == null) return;
            if (Flags.Shift && AllowFix)
            {
                SpareCoordinate = SpareCoordinate.GetProjectivePoint(SourcePoint.Pxy, Math.Tan(Utility.GetFixedAngle(
                        SourcePoint.Pxy.GetAngle(SpareCoordinate))));
            }
            PointD xy = Pad.PxyToXY(SpareCoordinate);
            Slope = SourcePoint.ToPointD().GetSlope(xy);
            PSlope = SourcePoint.Pxy.GetSlope(SpareCoordinate);
            DirectedAngle = SourcePoint.ToPointD().GetAngle(xy);
            ShowStatus($"{Resources.Translate("Creating")}{Resources.ColonSeparate}{Name}{Resources.LeftParenthesis}{string.Format(Resources.Translate("Of"), Resources.JoinLocalizedString("Direction", "Point"), Resources.Translate("Coordinate"))}{Resources.ColonSeparate}{Pad.PxyToMath(SpareCoordinate)}{Resources.CommaSeparate}{Resources.Translate("DirectedAngle")}{Resources.ColonSeparate}{Pad.ShowRad(DirectedAngle)}");
            base.ComponentBuilding(component);
        }
        public void CreateComponents(PointBase point, bool p2DoBuilding = false)
        {
            if (point == null) return;
            if (SourcePoint == null)
            {
                SourcePoint = point;
                SpareCoordinate_ = SourcePoint.Pxy;
                Pad.TrackObj = this;
            }
            else
            {
                if (p2DoBuilding)
                {
                    Pad.HostTrackComponentBuilding(point.Pxy);
                }
                DirectionPoint = point;
                base.CreateComponents();
            }
        }
        public void CreateComponents(string pointName, PointCollectionBase[] collections = null)
        {
            if (collections == null)
            {
                if (SourcePoint == null)
                {
                    collections = Universal.GenerateInstanceArray();
                }
                else
                {
                    collections = new PointCollectionBase[1];
                    if (Flags.Shift && AllowFix)
                    {
                        collections[0] = new Ray(SourcePoint.ToPointD(), SourcePoint.ToPointD().GetAngle(Pad.PxyToXY(SpareCoordinate)));
                    }
                    else
                    {
                        collections[0] = new Universal();
                    }
                    collections[0].Exceptions = new HashSet<PointCollectionBase>() { new DiscontinuityPoint(SourcePoint.ToPointD()) };
                }
            }
            CreateComponents(Pad.CreatePoint(pointName, SpareCoordinate_, true, collections));
        }
        public override void CreateComponents()
        {
            if (SourcePoint == null)
            {
                CreateComponents(Resources.JoinLocalizedString("Source", "Point"));
            }
            else
            {
                CreateComponents(Resources.JoinLocalizedString("Direction", "Point"));
            }
        }
        public override double NewSlope
        {
            get
            {
                return SourcePoint.NewXY.GetSlope(DirectionPoint.NewXY);
            }
        }
        public override double NewPSlope
        {
            get
            {
                return SourcePoint.NewPxy.GetSlope(DirectionPoint.NewPxy);
            }
        }
        public override double NewDirectedAngle
        {
            get
            {
                return SourcePoint.NewXY.GetAngle(DirectionPoint.NewXY);
            }
        }
    }
}
